package trumpet.video;

import java.io.IOException;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.CannotRealizeException;
import javax.media.MediaLocator;
import javax.media.NoDataSourceException;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.protocol.DataSource;

/**
 *
 * @author vsemaphore
 */
public class Manager extends Thread {
           
    public static final String BROADCAST_ADDRESS_DEFAULT = "255.255.255.255";
    public static final String MULICAST_ADDRESS_DEFAULT = "224.112.112.122";
    public static final String DEFAULT_DATA_SOURCE = "vfw://0";
    
    protected static Manager _instance;
    
    public static Manager getInstance()
    {
        if ( ! (_instance instanceof Manager) ) {
            _instance = new Manager();
        }
        return _instance;
    }
    
    protected AVTransmit2 _transmit;
    protected int _serverPort;
    
    public Manager()
    {
        String addr = getBroadcastAddress();
        int port = getServerPort();
        _transmit = new AVTransmit2(getDataSource(), addr, port, null);
        System.out.println("Video server started: " + addr + ":" + port);
    }
    
    public String getMulticastAddress()
    {
        return MULICAST_ADDRESS_DEFAULT;
    }
    
    public String getBroadcastAddress()
    {
        return BROADCAST_ADDRESS_DEFAULT;
    }
    
    protected void generateServerPort()
    {
        _serverPort = (new Random().nextInt()%255 + 10000) * 2;
    }
    
    public int getServerPort()
    {
        if ( _serverPort == 0) {
            generateServerPort();
        }
        return _serverPort;
    }
    
    public DataSource getDataSource()
    {
        DataSource ds = null;
        try {
            ds = javax.media.Manager.createDataSource(new MediaLocator(DEFAULT_DATA_SOURCE));
        } catch (IOException ex) {
            Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoDataSourceException ex) {
            Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return ds;
    }
    
    public void handle()
    {
        start();
    }
    
    public void run()
    {
        String result = _transmit.start();
        
        if (result != null) {
            System.err.println("Video manager error: " + result);
        }
    }
    
    public Player createPlayer(int id)
    {
        Player player = null;
        String addr = "rtp://" + getMulticastAddress() + ":" + id + "/video";
        try {
            player = javax.media.Manager.createRealizedPlayer(new MediaLocator(addr));
            System.out.println(addr);
            player.start();
        } catch (IOException ex) {
            Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoPlayerException ex) {
            Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (CannotRealizeException ex) {
            Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return player;
    }
}
